![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
This code can be restructured to remove the confusing Resume statement with a simpler Resume Next statement. The following routine moves the complex file reading code into the ReadData subroutine. If an error occurs inside ReadData, this routine uses the Resume Next statement to continue execution after ReadData. This code is easier to understand than the previous version.
Private Sub LoadData(ByVal file_name As String)
Dim fnum As Integer
Open a file.
fnum = FreeFile
Open file_name For Input As #fnum
Read from the file, process data, etc.
On Error GoTo ReadError
ReadData fnum
Close the file.
Close #fnum
Exit Sub
ReadError:
MsgBox Error & Str$(Err.Number) & _
vbCrLf & Err.Description
Resume Next
End Sub
Use GoTo to SimplifyGoTo is sometimes also used when the alternative would be more awkward and confusing. For example, a single GoTo statement can allow a program to break out of a deeply nested series of loops. The following code executes a series of loops. If it finds the condition value(i, j, k) = 0, it uses a GoTo statement to break out of all of the loops in one step.
Do While Timer < stop_time
For i = 1 To 100
For j = i + 1 To 1000
Do something here.
:
If value(i, j) = 0 Then GoTo ExitLoops
Next j
Next i
Loop
ExitLoops:
Compare this to the following code that breaks out of the loops without using a GoTo statement. This code is reasonable, but the previous version is simpler.
Dim found_entry As Boolean
found_entry = False
Do While Timer < stop_time
For i = 1 To 100
For j = i + 1 To 1000
Do something here.
:
If value(i, j) = 0 Then
found_entry = True
Exit For
End If
if found_entry Then Exit For
Next j
if found_entry Then Exit For
Next i
if found_entry Then Exit Do
Loop
Exit in One PlaceSome developers believe that every routine should always exit from a single point. That makes it easy to verify that any special cleanup code is properly executed. The following subroutine opens two data files and reads from them. It uses error handlers with appropriate Resume statements to ensure that it closes the files properly and always exits at the same Exit Sub statement.
Private Sub LoadData( _
ByVal file_name1 As String, _
ByVal file_name2 As String)
Dim fnum1 As Integer
Dim fnum2 As Integer
Open the files.
On Error GoTo OpenError1
fnum1 = FreeFile
Open file_name1 For Input As #fnum1
On Error GoTo OpenError2
fnum2 = FreeFile
Open file_name1 For Input As #fnum2
Read from the file, process data, etc.
On Error GoTo ReadError
:
Close the files.
CloseFile1:
On Error GoTo CloseError2
Close #fnum2
CloseFile2:
On Error GoTo CloseError1
Close #fnum1
LoadDataDone:
On Error Resume Next
Always exit here.
Exit Sub
******************************
Error handlers (code omitted).
OpenError1:
:
Resume LoadDataDone
OpenError2:
:
Resume CloseFile1 Close file 1 only.
ReadError:
:
Resume CloseFile2 Close both files.
CloseError2:
:
Resume CloseFile1 Close file 1 only.
CloseError1:
:
Resume LoadDataDone Weve cleaned up all we can.
End Sub
Making a routine exit at a single point generally requires lots of error handlers, GoTos, and labeled lines. This example required six On Error statements, five error handlers, and eight labeled lines. This makes the routine look somewhat cluttered, but most of this code is required anyway, no matter how the routine is organized. The subroutine in this example must handle errors in quite a few situations. It must be prepared to close zero, one, or both of the files depending on which files are open. Handling all those situations makes the routine fairly complex in any case. Exit before Error HandlersAlways place an Exit Sub statement before error-handling code so the routine does not continue past the end of the normal code and fall into the error handlers.
:
Done with normal processing.
Exit Sub
***************
Error handlers.
***************
OpenFileError:
:
Place error handlers together at the end of the routine. Dont mix error-handling code with normal code. Dont Use IIFThe IIF statement has the syntax variable = IIF(expression, true_value, false_value) Here, expression is a logical expression. This statement gives the variable the value true_value if the expression is True and false_value if it is False. IIF is confusing so you should not use it. Use an If Then Else statement instead. The following code compares the times required by IIF and If Then Else. The If Then Else statement is not only easier to understand, it also takes only 25 percent as long as IIF.
Private Sub TimeIIF()
Const NUM_TESTS = 100000
Dim start_time As Single
Dim stop_time As Single
Dim i As Long
Dim txt As String
Try IFF.
start_time = Timer
For i = 1 To NUM_TESTS
txt = IIf(i < 5000, _
Its a smaller value, _
Its a larger value)
Next i
stop_time = Timer
MsgBox Format$(stop_time - start_time, 0.00)
Try If Then Else.
start_time = Timer
For i = 1 To NUM_TESTS
If i < 5000 Then
txt = Its a smaller value
Else
txt = Its a larger value
End If
Next i
stop_time = Timer
MsgBox Format$(stop_time - start_time, 0.00)
End Sub
IIF also has interacts strangely with routines that have side effects because it always evaluates both assignment values whether the condition is True or not. In the following code, IFF executes both TrueFunction and FalseFunction even though it does not really need the value of FalseFunction. variable = IIF(True, TrueFunction, FalseFunction) Prevent confusion by using If Then Else instead of IIF. Watch for Overflow and UnderflowWatch out for expressions that can produce overflow or underflow. For example, the following function produces an overflow error if its input parameter is greater than 16383. It produces an underflow if the parameter is less than 16384.
Function DoubleIt(ByVal x As Integer) As Integer
DoubleIt = 2 * x
End Function
|
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|